﻿using System.Diagnostics.CodeAnalysis;
using Admin.NET.Application.Const;
using Admin.NET.Application.Dto;
using Admin.NET.Application.Entity;
using Furion.DataEncryption;
using NewLife.Reflection;

namespace Admin.NET.Application.Service;


/// <summary>
/// SleepRecord服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class SleepRecordService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<SleepRecord> _rep;

    public SleepRecordService(SqlSugarRepository<SleepRecord> rep)
    {
        _rep = rep;
    }

    /// <summary>
    /// 分页查询SleepRecord
    /// </summary>
    /// <param name="input"></param>d
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    public async Task<SqlSugarPagedList<SleepRecord>> Page(SleepRecordInput input)
    {
        var query = _rep.AsQueryable()
            .WhereIF(input.State.HasValue, u => u.State == input.State)
            .WhereIF(input.Year.HasValue, u => u.StartTime.Value.Year == input.Year)
            .WhereIF(input.Month.HasValue, u => u.StartTime.Value.Month == input.Month)
            .Where(a => a.IsDelete == false)
            .Select<SleepRecord>();

        query = query.OrderBuilder(input, "", "StartTime");
        return await query.ToPagedListAsync(input.Page, input.PageSize);
    }


    /// <summary>
    /// 月份查询
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "MonthSearch")]
    [SuppressMessage("ReSharper.DPA", "DPA0006: Large number of DB commands", MessageId = "计数: 430")]
    public async Task<List<MonthSearchOutPut>> MonthSearch(MonthSearchInput input)
    {
         
        var query =   _rep.AsQueryable()
            .WhereIF(input.Year.HasValue, u => u.StartTime.Value.Year == input.Year)
            .WhereIF(input.Month.HasValue, u => u.StartTime.Value.Month == input.Month)
            .Where(a => a.IsDelete == false)
            .OrderBy(s=>s.StartTime,OrderByType.Asc)
            .Select<MonthSearchOutPut>();

        var list = await query.ToListAsync();
        return list;
    }


    /// <summary>
    /// 增加SleepRecord
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    public async Task Add(AddSleepRecordInput input)
    {
        var isExist = await _rep.AsQueryable()
            .Filter(null, true)
            .AnyAsync(u => u.NowTime == input.NowTime);

        if (isExist) throw Oops.Oh("该日期已存在:" + input.NowTime);

        CalculateTime(input);

        var entity = input.Adapt<SleepRecord>();
        await _rep.InsertAsync(entity);
    }

    /// <summary>
    /// 计算时间
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="AppFriendlyException"></exception>
    private SleepRecordBaseInput CalculateTime(SleepRecordBaseInput input)
    {
        //持续时间
        input.Duration = input.EndTime - input.StartTime;

        if (input.Duration is { Days: >= 1 })
        {
            throw Oops.Oh("持续时间超过一天！");
        }

        if (input.Duration is { TotalHours: <= 6 })
        {
            input.State = SleepStateEnum.Agrypnia;
        }
        else
        {
            //前一天晚上睡
            if (input.StartTime is { Hour: > 12 })
            {
                input.State = SleepStateEnum.Fine;
            }
            else
            {
                input.State = SleepStateEnum.Common;
            }
        }

        return input;
    }

    /// <summary>
    /// 删除SleepRecord
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    public async Task Delete(DeleteSleepRecordInput input)
    {
        var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _rep.FakeDeleteAsync(entity); //假删除
        //await _rep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 更新SleepRecord
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    public async Task Update(UpdateSleepRecordInput input)
    {
        CalculateTime(input);

        var entity = input.Adapt<SleepRecord>();
        await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }

    /// <summary>
    /// 获取SleepRecord
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    public async Task<SleepRecord> Get([FromQuery] QueryByIdSleepRecordInput input)
    {
        return await _rep.GetFirstAsync(u => u.Id == input.Id);
    }

    /// <summary>
    /// 获取SleepRecord列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    public async Task<List<SleepRecordOutput>> List([FromQuery] SleepRecordInput input)
    {
        return await _rep.AsQueryable().Select<SleepRecordOutput>().ToListAsync();
    }
}